package com.settlement.system.controller;

import com.settlement.system.common.exception.ServiceException;
import com.settlement.system.common.util.SecurityUtils;
import com.settlement.system.common.util.common.CommonAcsUtil;
import com.settlement.system.common.util.common.SystemUserUtil;
import com.settlement.system.mapper.security.userdetails.SysUserDetails;
import com.settlement.system.model.entity.common.*;
import com.settlement.system.reply.ObjectDataResponse;
import com.settlement.system.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 退款稽核单据明细表 前端控制器
 *
 * @author xiaochuan
 * @since 2020-06-24
 */

@Api(tags = "退款稽核单据明细表", description = "退款稽核单据明细表")
@RestController
@RequestMapping("/refund/audit/bill/dtl")
@Slf4j
public class TblRefundAuditBillDtlController extends BaseController<TblRefundAuditBillDtl> {

    @Resource
    private ITblRefundAuditBillDtlService tblRefundAuditBillDtlService;

    @Resource
    private ITblRefundAuditBillService tblRefundAuditBillService;

    @Resource
    private ITblAcsRoleBillStatusService tblAcsRoleBillStatusService;

    @Resource
    private ITblAcsUserRoleAuthorityService tblAcsUserRoleAuthorityService;

    @Override
    public IBaseService init() {
        return tblRefundAuditBillDtlService;
    }


    @ApiOperation("插入退款单据操作明细")
    @RequestMapping(value = "saveDtl", method = {RequestMethod.POST})
    @ResponseBody
    public ObjectDataResponse saveRefundDtl(@RequestBody TblRefundAuditBillDtl currentDtl, HttpServletRequest request) {
        ObjectDataResponse rsp = new ObjectDataResponse();
        try {
            TblRefundAuditBillDtl lastDtl = new TblRefundAuditBillDtl();
            TblRefundAuditBill bill = new TblRefundAuditBill();
            if (!validateSave(currentDtl, rsp)) {
                return rsp;
            }
            setTblRefundAuditBill(bill, currentDtl, lastDtl);
            tblRefundAuditBillDtlService.insertDtl(bill, currentDtl, lastDtl);
            return new ObjectDataResponse(200, "提交成功");
        } catch (Exception ex) {
            log.error("插入退款单据操作明细", ex);
            return new ObjectDataResponse(500, "提交失败，请联系管理员！");
        }
    }

    /**
     * @param currentDtl
     * @param rsp
     */
    private boolean validateSave(TblRefundAuditBillDtl currentDtl, ObjectDataResponse rsp) throws ServiceException {
        String billNo = currentDtl.getBillNo();
        if (StringUtils.isEmpty(billNo)) {
            log.error("提交单号为空，不逊于提交");
            rsp.setCode(500);
            rsp.setMessage("提交单号为空，不逊于提交");
            return false;
        }
        try {
            Map<String, Object> params = new HashMap<>(16);
            params.put("billNo", billNo);
            List<TblRefundAuditBillDtl> billList = tblRefundAuditBillDtlService.selectRoleStatus(params);
            if (CollectionUtils.isEmpty(billList)) {
                log.error("单号{}已经被归档，不允许在进行操作", billNo);
                rsp.setCode(500);
                rsp.setMessage("提交单号已经被归档，不允许在进行保存了！");
                return false;
            }

            SysUserDetails user = SecurityUtils.getUser();;
            //判断下最新一条记录是不是进行撤销用户所属角色，并且用户具有写的权限
            Map<String, Object> paramsUser = new HashMap<>(16);
            paramsUser.put("roleNo", billList.get(0).getRoleNo());
            paramsUser.put("authorityNo", "auth_002");
            paramsUser.put("loginName", user.getUsername());
            List<TblAcsUserRoleAuthority> auth = tblAcsUserRoleAuthorityService.selctAllUserInfo(paramsUser);
            if (CollectionUtils.isEmpty(auth)) {
                log.error("单号{}单据状态已经与你不匹配，请确认当前单据是否已经被处理！", billNo);
                rsp.setCode(500);
                rsp.setMessage("单据状态已经与你不匹配，请确认当前单据是否已经被处理！");
                return false;
            }
            return true;
        } catch (ServiceException e) {
            throw e;
        }

    }


    @ApiOperation("撤销操作")
    @RequestMapping(value = "cancel", method = {RequestMethod.POST})
    @ResponseBody
    public ObjectDataResponse cancel(@RequestBody TblRefundAuditBillDtl dtl, HttpServletRequest request) {
        ObjectDataResponse rsp = new ObjectDataResponse();
        try {
            String billNo = dtl.getBillNo();

            SysUserDetails user = SecurityUtils.getUser();;

            String loginName = user.getUsername();

            if (!validateBill(billNo, loginName, rsp)) {
                return rsp;
            }

            tblRefundAuditBillDtlService.updateBillStatus(user, billNo);

            rsp.setCode(200);
            rsp.setMessage("撤销成功");
            return rsp;
        } catch (Exception ex) {
            log.error("撤销数据异常", ex);
            rsp.setCode(500);
            rsp.setMessage("撤销失败，请联系管理员！");
            return rsp;
        }
    }

    /**
     * 校验单据是否可以进行撤销操作
     *
     * @param billNo    单号
     * @param loginName 登录用户名
     * @param rsp       返回结果集
     * @throws ServiceException
     */
    private boolean validateBill(String billNo, String loginName, ObjectDataResponse rsp) throws ServiceException {
        try {
            if (StringUtils.isEmpty(billNo)) {
                log.error("撤销单号{}不能为空，不允许撤销", billNo);
                rsp.setCode(500);
                rsp.setMessage("撤销单号不能为空，不允许撤销");
                return false;
            }

            Map<String, Object> params = new HashMap<>(16);
            params.put("billNo", billNo);
            List<TblRefundAuditBillDtl> lastEffectiveList = tblRefundAuditBillDtlService.selectLastEffective(params);
            if (CollectionUtils.isEmpty(lastEffectiveList)) {
                log.error("单号{}当前处理状态没有处理过的记录，不允许进行撤销操作！", billNo);
                rsp.setCode(500);
                rsp.setMessage("当前处理状态没有处理过的记录，不允许进行撤销操作！");
                return false;
            }
            final String revokeString = "撤销";
            if (StringUtils.equals(lastEffectiveList.get(0).getStatusName(), revokeString)) {
                log.error("单号{}当前状态已经被处理过，不允许进行撤销操作！", billNo);
                rsp.setCode(500);
                rsp.setMessage("当前状态已经被处理过，不允许进行撤销操作！");
                return false;
            }

            List<TblRefundAuditBillDtl> lastSecondList = tblRefundAuditBillDtlService.selectLastSecond(params);
            if (CollectionUtils.isEmpty(lastSecondList)) {
                log.error("单号{}无处理过的数据，不允许进行撤销操作！", billNo);
                rsp.setCode(500);
                rsp.setMessage("无处理过的数据，不允许进行撤销操作！");
                return false;
            }

            //判断下最新一条记录是不是进行撤销用户所属角色，并且用户具有写的权限
            Map<String, Object> paramsUser = new HashMap<>(16);
            paramsUser.put("roleNo", lastSecondList.get(0).getRoleNo());
            paramsUser.put("authorityNo", "auth_002");
            paramsUser.put("loginName", loginName);
            List<TblAcsUserRoleAuthority> allIngo = tblAcsUserRoleAuthorityService.selctAllUserInfo(paramsUser);
            if (CollectionUtils.isEmpty(allIngo)) {
                log.error("单号{}最有一条操作用户权限与你不匹配，不允许进行撤销操作！", billNo);
                rsp.setCode(500);
                rsp.setMessage("最有一条操作用户权限与你不匹配，不允许进行撤销操作！");
                throw new ServiceException("最有一条操作用户权限与你不匹配，不允许进行撤销操作！");
            }

            if (StringUtils.isEmpty(lastEffectiveList.get(0).getLastEffectiveId())) {
                log.error("未找到{}单号的待处理情况已经根节点，不允许在撤销", billNo);
                rsp.setCode(500);
                rsp.setMessage("找到该单号的操作记录，不允许撤销");
                return false;
            }

            return true;

        } catch (Exception e) {
            log.error("单号{}校验撤销权限异常！", billNo);
            throw new ServiceException(e);
        }
    }


    private void setTblRefundAuditBill(TblRefundAuditBill bill, TblRefundAuditBillDtl currentDtl, TblRefundAuditBillDtl lastDtl) throws ServiceException {
        try {
            SysUserDetails user = SecurityUtils.getUser();;
            //查询此单是否已经被处理
            Map<String, Object> params = new HashMap<>(16);
            params.put("billNo", currentDtl.getBillNo());
            List<TblRefundAuditBill> billList = tblRefundAuditBillService.selectByParam(params);
            if (!CollectionUtils.isEmpty(billList)) {
                if (StringUtils.isEmpty(billList.get(0).getFirstServicePerson())) {
                    bill.setFirstServicePersonName(user.getUsername());
                    bill.setFirstServicePerson(user.getUsername());
                }
                //lastDtl.setId(billList.get(0).getDealDtlId());
            }

            /*if(StringUtils.equals("实物追回",currentDtl.getLossReasonName())){
                currentDtl.setBillStatusName(billList.get(0).getBillStatusName());
                currentDtl.setBillStatusNo(billList.get(0).getBillStatusNo());
                currentDtl.setResponsibleName(billList.get(0).getResponsibleName());
                currentDtl.setResponsibleNo(billList.get(0).getResponsibleNo());
            }*/
            PropertyUtils.copyProperties(bill, currentDtl);
            currentDtl.setId(CommonAcsUtil.generateUUId());
            currentDtl.setCreateTime(new Date());
            currentDtl.setCreateUser(user.getUsername());
            currentDtl.setUserName(user.getUsername());
            currentDtl.setLoginName(user.getUsername());

            bill.setDealDtlId(currentDtl.getId());
            bill.setUpdateTime(new Date());
            bill.setUpdateUser(user.getUsername());

            params.put("billStatusNo", currentDtl.getBillStatusNo());
            List<TblAcsRoleBillStatus> list = tblAcsRoleBillStatusService.selectByParam(params);
            currentDtl.setRoleNo(list.get(0).getRoleNo());
            currentDtl.setStatusName("确认");
            currentDtl.setUpdateTime(new Date());
            currentDtl.setUpdateUser(user.getUsername());

            List<TblRefundAuditBillDtl> dtlList = tblRefundAuditBillDtlService.selectByParam(params);
            currentDtl.setOrderField(dtlList.get(0).getOrderField() + 1);
            currentDtl.setLastEffectiveId(billList.get(0).getDealDtlId());
        } catch (Exception e) {
            log.error("组装单据Model流转异常", e);
            throw new ServiceException(e);
        }
    }

    @ApiOperation("批量插入退款稽核单据操作明细")
    @RequestMapping(value = "batchSaveRefundCheckDtl", method = {RequestMethod.POST})
    @ResponseBody
    public ObjectDataResponse batchSaveRefundCheckDtl(@RequestBody TblRefundAuditBillDtl tblRefundAuditBillDtl, HttpServletRequest request) {
        ObjectDataResponse rsp = new ObjectDataResponse();
        try {
            log.info("批量处理退款稽核，接收数据={}", tblRefundAuditBillDtl);
            if (StringUtils.isBlank(tblRefundAuditBillDtl.getBillNo())) {
                return new ObjectDataResponse(500, "单据编码不能为空");
            }
            tblRefundAuditBillDtlService.batchSaveRefundCheckDtl(tblRefundAuditBillDtl);
            return new ObjectDataResponse(200, "提交成功");
        } catch (Exception ex) {
            log.error("批量插入退款稽核单据操作明细", ex);
            return new ObjectDataResponse(500, "提交失败，请联系管理员！");
        }
    }

}

